/**
 * 缓存管理器 - 基于ai-writer-lite项目的缓存系统
 * 提供内存缓存和TTL管理
 */

export interface CacheEntry<T> {
  data: T
  timestamp: number
  ttl: number
  hits: number
}

export interface CacheStats {
  size: number
  hitRate: number
  totalHits: number
  totalMisses: number
  oldestEntry?: number
  newestEntry?: number
}

export interface CacheOptions {
  maxSize?: number
  defaultTTL?: number // 秒
  enableStats?: boolean
  cleanupInterval?: number // 秒
}

export class CacheManager<T = any> {
  private cache: Map<string, CacheEntry<T>> = new Map()
  private maxSize: number
  private defaultTTL: number
  private enableStats: boolean
  private cleanupInterval: number
  private cleanupTimer?: NodeJS.Timeout

  // 统计数据
  private totalHits = 0
  private totalMisses = 0

  constructor(options: CacheOptions = {}) {
    this.maxSize = options.maxSize || 1000
    this.defaultTTL = options.defaultTTL || 3600 // 1小时
    this.enableStats = options.enableStats !== false
    this.cleanupInterval = options.cleanupInterval || 300 // 5分钟

    // 启动定期清理
    this.startCleanup()
  }

  /**
   * 设置缓存项
   */
  public set(key: string, data: T, ttl?: number): void {
    const entry: CacheEntry<T> = {
      data,
      timestamp: Date.now(),
      ttl: ttl || this.defaultTTL,
      hits: 0,
    }

    // 如果缓存已满，移除最旧的项
    if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
      this.evictOldest()
    }

    this.cache.set(key, entry)
  }

  /**
   * 获取缓存项
   */
  public get(key: string): T | null {
    const entry = this.cache.get(key)

    if (!entry) {
      if (this.enableStats) {
        this.totalMisses++
      }
      return null
    }

    // 检查是否过期
    if (this.isExpired(entry)) {
      this.cache.delete(key)
      if (this.enableStats) {
        this.totalMisses++
      }
      return null
    }

    // 更新命中统计
    if (this.enableStats) {
      entry.hits++
      this.totalHits++
    }

    return entry.data
  }

  /**
   * 检查缓存项是否存在且未过期
   */
  public has(key: string): boolean {
    const entry = this.cache.get(key)
    return entry !== undefined && !this.isExpired(entry)
  }

  /**
   * 删除缓存项
   */
  public delete(key: string): boolean {
    return this.cache.delete(key)
  }

  /**
   * 清空所有缓存
   */
  public clear(): void {
    this.cache.clear()
    if (this.enableStats) {
      this.totalHits = 0
      this.totalMisses = 0
    }
  }

  /**
   * 获取缓存大小
   */
  public size(): number {
    return this.cache.size
  }

  /**
   * 获取所有缓存键
   */
  public keys(): string[] {
    return Array.from(this.cache.keys())
  }

  /**
   * 获取缓存统计信息
   */
  public getStats(): CacheStats {
    const now = Date.now()
    let oldestTimestamp: number | undefined
    let newestTimestamp: number | undefined

    for (const entry of this.cache.values()) {
      if (oldestTimestamp === undefined || entry.timestamp < oldestTimestamp) {
        oldestTimestamp = entry.timestamp
      }
      if (newestTimestamp === undefined || entry.timestamp > newestTimestamp) {
        newestTimestamp = entry.timestamp
      }
    }

    const totalRequests = this.totalHits + this.totalMisses
    const hitRate = totalRequests > 0 ? (this.totalHits / totalRequests) * 100 : 0

    return {
      size: this.cache.size,
      hitRate: Math.round(hitRate * 100) / 100,
      totalHits: this.totalHits,
      totalMisses: this.totalMisses,
      oldestEntry: oldestTimestamp,
      newestEntry: newestTimestamp,
    }
  }

  /**
   * 手动清理过期项
   */
  public cleanup(): number {
    let removedCount = 0
    const now = Date.now()

    for (const [key, entry] of this.cache.entries()) {
      if (this.isExpired(entry, now)) {
        this.cache.delete(key)
        removedCount++
      }
    }

    return removedCount
  }

  /**
   * 获取即将过期的项
   */
  public getExpiringSoon(withinSeconds: number = 300): Array<{key: string; ttl: number}> {
    const now = Date.now()
    const expiring: Array<{key: string; ttl: number}> = []

    for (const [key, entry] of this.cache.entries()) {
      const remainingTTL = entry.ttl * 1000 - (now - entry.timestamp)
      if (remainingTTL > 0 && remainingTTL <= withinSeconds * 1000) {
        expiring.push({
          key,
          ttl: Math.ceil(remainingTTL / 1000),
        })
      }
    }

    return expiring.sort((a, b) => a.ttl - b.ttl)
  }

  /**
   * 更新缓存项的TTL
   */
  public updateTTL(key: string, newTTL: number): boolean {
    const entry = this.cache.get(key)
    if (!entry) {
      return false
    }

    entry.ttl = newTTL
    entry.timestamp = Date.now() // 重置时间戳
    return true
  }

  /**
   * 获取缓存项的剩余TTL
   */
  public getRemainingTTL(key: string): number {
    const entry = this.cache.get(key)
    if (!entry) {
      return -1
    }

    const now = Date.now()
    const remainingTTL = entry.ttl * 1000 - (now - entry.timestamp)
    return Math.max(0, Math.ceil(remainingTTL / 1000))
  }

  /**
   * 销毁缓存管理器
   */
  public destroy(): void {
    if (this.cleanupTimer) {
      clearInterval(this.cleanupTimer)
      this.cleanupTimer = undefined
    }
    this.clear()
  }

  private isExpired(entry: CacheEntry<T>, now: number = Date.now()): boolean {
    return (now - entry.timestamp) > (entry.ttl * 1000)
  }

  private evictOldest(): void {
    let oldestKey: string | undefined
    let oldestTimestamp: number | undefined

    for (const [key, entry] of this.cache.entries()) {
      if (oldestTimestamp === undefined || entry.timestamp < oldestTimestamp) {
        oldestKey = key
        oldestTimestamp = entry.timestamp
      }
    }

    if (oldestKey) {
      this.cache.delete(oldestKey)
    }
  }

  private startCleanup(): void {
    if (this.cleanupInterval > 0) {
      this.cleanupTimer = setInterval(() => {
        this.cleanup()
      }, this.cleanupInterval * 1000)
    }
  }

  /**
   * 生成缓存键的辅助方法
   */
  public static generateKey(...parts: string[]): string {
    return parts.join(':')
  }

  /**
   * 基于对象内容生成缓存键
   */
  public static generateKeyFromObject(obj: any): string {
    const str = JSON.stringify(obj, Object.keys(obj).sort())
    return Buffer.from(str).toString('base64').substring(0, 32)
  }
}

// 全局缓存实例
export class GlobalCacheManager {
  private static caches: Map<string, CacheManager> = new Map()

  public static getCache<T = any>(name: string, options?: CacheOptions): CacheManager<T> {
    if (!this.caches.has(name)) {
      this.caches.set(name, new CacheManager<T>(options))
    }
    return this.caches.get(name) as CacheManager<T>
  }

  public static destroyCache(name: string): boolean {
    const cache = this.caches.get(name)
    if (cache) {
      cache.destroy()
      return this.caches.delete(name)
    }
    return false
  }

  public static destroyAllCaches(): void {
    for (const [name, cache] of this.caches.entries()) {
      cache.destroy()
    }
    this.caches.clear()
  }

  public static getCacheStats(): Record<string, CacheStats> {
    const stats: Record<string, CacheStats> = {}
    for (const [name, cache] of this.caches.entries()) {
      stats[name] = cache.getStats()
    }
    return stats
  }
}

// 导出便捷函数
export const getAICache = <T = any>(options?: CacheOptions): CacheManager<T> => {
  return GlobalCacheManager.getCache<T>('ai-responses', {
    maxSize: 500,
    defaultTTL: 1800, // 30分钟
    cleanupInterval: 300, // 5分钟清理一次
    ...options,
  })
}